package com.hunter.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JEditorPane;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.SwingWorker;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;

import org.apache.log4j.Logger;
import org.apache.lucene.search.Query;

import com.hunter.desktop.file.FileData;
import com.hunter.desktop.file.RealFile;
import com.hunter.lucene.util.UserData;
import com.hunter.lucene.util.index.IndexException;
import com.hunter.lucene.util.index.Writable;
import com.hunter.lucene.util.search.QuerySession;
import com.hunter.lucene.util.search.Searchable;
import com.hunter.util.ConfigManager;
import com.hunter.util.HistoryUtil;
import com.hunter.util.LogUtil;
import com.hunter.util.PropertiesUtil;
import com.hunter.util.QueryManager;
import com.hunter.util.SystemUtil;
import com.mkk.swing.SwingUtil;
import com.mkk.util.PageTool;

/**
 * 2010-9-1 下午10:49:57<br>
 * 搜索结果显示界面
 * 
 * @author mkk
 */
public class SearchPanel extends JPanel {

	private static final long serialVersionUID = 1L;

	private static Logger log = Logger.getLogger(SearchPanel.class);
	// main
	private MainFrame main;
	// 搜索关键字
	private String keyWord;
	// 搜索耗时
	private long times;
	// 搜索框
	private JTextField textField1;
	// 搜索按钮
	private JButton button1;
	// 显示搜索结果标签
	private JLabel label1;
	// 分页按钮
	private JButton button3, button4;
	// 页数框
	private JFormattedTextField formatField1;
	// 分页状态栏标签
	private JLabel label2;
	// 结果显示面板
	private JEditorPane editPanel1;
	// 每页显示的搜索结果子集
	private List<FileData> subDatas;
	// 分页工具类对象
	private PageTool<FileData> pageTool;
	// 搜索结果
	private List<FileData> resList;
	// 右键菜单
	private JPopupMenu popMeun;
	private JMenu openMenu;
	private JMenuItem item1, item2, item3, item4, item5, item6;
	private JMenuItem fileItems[] = new JMenuItem[PropertiesUtil.DEFAULT_PAGE_SIZE];
	// 确认是否删除不存在的索引文件
	private JCheckBox checkBox1;
	// 高级搜索标签
	private JLabel label4;
	// 高级搜索面板
	private JPanel panel1;
	// 最后访问的页码,用于实现后退功能
	private int lastPage;
	// 高级搜索界面组件
	private String[] labStrs = { "搜索隐藏文件", "搜索文件内容", "指定时间段搜索", "指定后缀名搜索" };
	private JLabel labs[] = new JLabel[labStrs.length];
	private JCheckBox boxs[] = new JCheckBox[labStrs.length];
	// autocomplete window
	private JWindow window;
	// autocomplete result list
	private JList list;
	// whether first show this panel
	private boolean firstShow = true;

	private HistoryUtil historyUtil = HistoryUtil.getHistoryUtil();

	/**
	 * default constructor
	 */
	public SearchPanel() {
		this.initComponents();
	}

	/**
	 * constructor
	 * 
	 * @param keyWord
	 *            搜索关键字
	 * @param resList
	 *            搜索结果
	 * @param times
	 *            搜索耗时
	 * @param main
	 *            主界面
	 */
	public SearchPanel(MainFrame main, String keyWord, long times,
			List<FileData> resList) {
		this.main = main;
		this.keyWord = keyWord;
		this.times = times;
		this.resList = resList;
		this.pageTool = new PageTool<FileData>(resList,
				PropertiesUtil.DEFAULT_PAGE_SIZE);
		this.initComponents();
		this.processEvents();
		this.initDatas();
	}

	/**
	 * 初始化数据
	 */
	private void initDatas() {
		// 关键字
		this.textField1.setText(keyWord);
		// 搜索信息
		this.setSearchResultInfo(resList.size(), times);
		// 分页信息
		this.setPagesInfo(this.pageTool.getTotalpages(),
				PropertiesUtil.DEFAULT_PAGE_SIZE);
		// 显示首页搜索结果
		if (resList.size() > 0) {
			this.subDatas = this.pageTool.getFirstpageDatas();
			this.editPanel1.setText(SystemUtil.getPageInfo(subDatas));
			this.setOpenFileDirItems();
		} else {
			// 处理搜索无结果的情况
			this.editPanel1.setText(SystemUtil.getNullResultInfo(keyWord));
			textField1.requestFocus();
			this.openMenu.setEnabled(false);
		}
		// 检查按钮可用性
		this.checkButtons();

	}

	/**
	 * @return the textField1
	 */
	public JTextField getTextField1() {
		return textField1;
	}

	/**
	 * 设置分页状态栏信息
	 * 
	 * @param totalPage
	 *            总页数
	 * @param pageSize
	 *            每页显示数目
	 */
	private void setPagesInfo(int totalPage, int pageSize) {
		this.label2.setText("<html>共 <span style='color:blue'>" + totalPage
				+ "</span>页,每页显示 <span style='color:blue'>" + pageSize
				+ "</span>条搜索结果</html>");
		this.label2.setForeground(Color.GRAY);
	}

	/**
	 * 设置打开文件所在目录菜单信息
	 */
	private void setOpenFileDirItems() {
		if (this.subDatas == null) {
			return;
		}
		if (subDatas.size() == 0) {
			openMenu.setEnabled(false);
			return;
		} else {
			openMenu.setEnabled(true);
		}
		for (int i = 0; i < subDatas.size(); i++) {
			UserData ud = subDatas.get(i);
			if (ud instanceof RealFile) {
				fileItems[i].setVisible(true);
				fileItems[i].setText(((FileData) ud).getFileName());
			} else {
				fileItems[i].setVisible(false);
			}
		}
		if (subDatas.size() < fileItems.length) {
			for (int i = subDatas.size(); i < fileItems.length; i++) {
				fileItems[i].setVisible(false);
			}
		}
	}

	/**
	 * 设置搜索结果显示信息
	 * 
	 * @param count
	 *            搜索结果数
	 * @param times
	 *            搜索耗时
	 */
	private void setSearchResultInfo(int count, long times) {
		this.label1.setText("<html>共 <span style='color:red'>" + count
				+ "</span>条结果  (用时 <span style='color:red'>"
				+ SystemUtil.formatNumber((times / 1000d), "0.00")
				+ "</span>秒)</html>");
	}

	/**
	 * 检查按钮的可用性
	 */
	private void checkButtons() {
		boolean next = this.pageTool.hasNextpage();
		boolean previ = this.pageTool.hasPreviouspage();
		this.button3.setEnabled(previ);
		this.item1.setEnabled(previ);
		this.button4.setEnabled(next);
		this.item2.setEnabled(next);
		this.formatField1.setText(String.valueOf(this.pageTool.getCurrpage()));

	}

	/**
	 * 初始化组件
	 */
	private void initComponents() {
		this.setLayout(new BorderLayout());
		// north
		this.add(this.showNorthPanel(), BorderLayout.NORTH);
		// center
		JPanel panel2 = new JPanel();
		panel2.setLayout(new BorderLayout());
		// 高级搜索面板
		this.panel1 = new JPanel();
		this.panel1.setVisible(false);
		initTopSearchPanel();
		panel2.add(this.panel1, BorderLayout.NORTH);
		this.editPanel1 = new JEditorPane();
		this.editPanel1.setEditable(false);
		this.editPanel1.setContentType("text/html");
		panel2.add(new JScrollPane(this.editPanel1), BorderLayout.CENTER);
		this.add(panel2, BorderLayout.CENTER);
		// south
		this.add(this.showSouthPanel(), BorderLayout.SOUTH);
		// 右键菜单
		this.popMeun = new JPopupMenu();
		this.item6 = new JMenuItem("后退");
		item6.setAccelerator(KeyStroke.getKeyStroke('Z', InputEvent.CTRL_MASK));
		item6.setEnabled(false);
		popMeun.add(item6);
		popMeun.addSeparator();
		this.item1 = new JMenuItem("上一页(P)");
		item1.setMnemonic('P');
		popMeun.add(item1);
		this.item2 = new JMenuItem("下一页(N)");
		item2.setMnemonic('N');
		popMeun.add(item2);
		popMeun.addSeparator();
		this.item3 = new JMenuItem("全选");
		item3.setAccelerator(KeyStroke.getKeyStroke('A', InputEvent.CTRL_MASK));
		popMeun.add(item3);
		this.item4 = new JMenuItem("复制");
		item4.setAccelerator(KeyStroke.getKeyStroke('C', InputEvent.CTRL_MASK));
		popMeun.add(item4);
		popMeun.addSeparator();
		this.openMenu = new JMenu("打开文件所在目录");
		for (int i = 0; i < this.fileItems.length; i++) {
			fileItems[i] = new JMenuItem("文件" + i);
			this.openMenu.add(fileItems[i]);
		}
		popMeun.add(this.openMenu);
		popMeun.addSeparator();
		this.item5 = new JMenuItem("属性");
		popMeun.add(item5);
		this.editPanel1.setComponentPopupMenu(popMeun);
	}

	/**
	 * 初始化高级搜索面板
	 */
	private void initTopSearchPanel() {
		this.panel1.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		this.panel1.setLayout(new GridLayout(2, 5));
		for (int i = 0; i < labStrs.length; i++) {
			boxs[i] = new JCheckBox(labStrs[i]);
			labs[i] = new JLabel();
			panel1.add(boxs[i]);
			panel1.add(labs[i]);
		}
	}

	/**
	 * 南面面板
	 * 
	 * @return
	 */
	private JPanel showSouthPanel() {
		JPanel p = new JPanel();
		p.setLayout(new FlowLayout(FlowLayout.LEFT));
		p.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		p.add(Box.createHorizontalStrut(20));
		this.button3 = new JButton();
		this.button3.setIcon(SystemUtil.getIcon("previous1.gif"));
		this.button3.setBorder(BorderFactory.createEmptyBorder());
		this.button3.setToolTipText("上一页");
		this.button3.setEnabled(false);
		p.add(this.button3);
		this.formatField1 = new JFormattedTextField();
		formatField1.setColumns(3);
		formatField1.setFormatterFactory(new DefaultFormatterFactory(
				new NumberFormatter(new DecimalFormat("#0"))));
		this.formatField1.setBorder(BorderFactory.createLoweredBevelBorder());
		this.formatField1.setText("1");
		this.formatField1.setBackground(Color.WHITE);
		this.formatField1.setFont(this.formatField1.getFont().deriveFont(
				Font.BOLD));
		this.formatField1.setToolTipText("页码");
		p.add(this.formatField1);
		this.button4 = new JButton();
		this.button4.setIcon(SystemUtil.getIcon("next1.gif"));
		this.button4.setBorder(BorderFactory.createEmptyBorder());
		this.button4.setToolTipText("下一页");
		p.add(this.button4);
		p.add(Box.createHorizontalStrut(20));
		this.label2 = new JLabel();
		p.add(this.label2);
		return p;
	}

	/**
	 * 北面面板
	 * 
	 * @return
	 */
	private JPanel showNorthPanel() {
		JPanel p = new JPanel();
		p.setLayout(new FlowLayout(FlowLayout.LEFT));
		p.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		this.textField1 = new JTextField(40);
		this.textField1.setToolTipText("输入搜索内容");
		this.textField1.setBackground(Color.WHITE);
		this.textField1
				.setFont(this.textField1.getFont().deriveFont(Font.BOLD));
		this.textField1.setBorder(BorderFactory.createLoweredBevelBorder());
		p.add(this.textField1);
		this.button1 = new JButton();
		button1.setIcon(SystemUtil.getSearchIcon());
		button1.setBorder(BorderFactory.createEmptyBorder());
		this.button1.setToolTipText("搜索");
		p.add(this.button1);
		this.label4 = new JLabel("<html><a href='#'>高级</a></html>");
		this.label4.setToolTipText("高级搜索");
		this.label4.setCursor(new Cursor(Cursor.HAND_CURSOR));
		p.add(this.label4);
		p.add(Box.createHorizontalStrut(20));
		this.label1 = new JLabel();
		this.label1.setFont(new Font("宋体", Font.PLAIN, 11));
		this.label1.setForeground(new Color(0, 100, 10));
		p.add(this.label1);
		return p;
	}

	/**
	 * 
	 * 事件处理
	 */
	private void processEvents() {
		// 高级搜索界面显示事件
		this.label4.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				boolean visiable = panel1.isVisible();
				if (visiable) {
					label4.setText("<html><a href='#'>高级</a></html>");
					label4.setToolTipText("高级搜索");
				} else {
					label4.setText("<html><a href='#'>关闭</a></html>");
					label4.setToolTipText("关闭高级搜索");
				}
				panel1.setVisible(!visiable);
			}

			public void mouseEntered(MouseEvent e) {
				main.setInfo(label4.getToolTipText(), Color.BLACK);
			}

			public void mouseExited(MouseEvent e) {
				main.setInfo("欢迎使用 Hunter 1.0", Color.BLACK);
			}
		});
		// 上一页事件
		ActionListener preAction = new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				main.setInfo("执行中,请稍候...", Color.BLUE);
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						// 获取上一页数据
						subDatas = pageTool.getPreviouspageDatas();
						editPanel1.setText(SystemUtil.getPageInfo(subDatas));
						setOpenFileDirItems();
						// 检查按钮可用性
						checkButtons();
						// 后退
						if (!item6.isEnabled()) {
							item6.setEnabled(true);
						}
						lastPage = pageTool.getCurrpage() + 1;
						main.setInfo("欢迎使用 Hunter 1.0", Color.BLACK);
					}
				});

			}
		};
		this.button3.addActionListener(preAction);
		this.item1.addActionListener(preAction);
		// 下一页事件
		ActionListener nextAction = new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				main.setInfo("执行中,请稍候...", Color.BLUE);
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						// 获取下一页数据
						subDatas = pageTool.getNextpageDatas();
						editPanel1.setText(SystemUtil.getPageInfo(subDatas));
						setOpenFileDirItems();
						// 检查按钮可用性
						checkButtons();
						// 后退
						if (!item6.isEnabled()) {
							item6.setEnabled(true);
						}
						lastPage = pageTool.getCurrpage() - 1;
						main.setInfo("欢迎使用 Hunter 1.0", Color.BLACK);
					}
				});
			}
		};
		this.button4.addActionListener(nextAction);
		this.item2.addActionListener(nextAction);
		// 指定页码事件
		this.formatField1.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				main.setInfo("执行中,请稍候...", Color.BLUE);
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						String s = formatField1.getText();
						int i = Integer.parseInt(s);
						if (i > 0 && i <= pageTool.getTotalpages()) {
							lastPage = pageTool.getCurrpage();
							subDatas = pageTool.getPageDatas(i);
							editPanel1
									.setText(SystemUtil.getPageInfo(subDatas));
							setOpenFileDirItems();
							// 检查按钮可用性
							checkButtons();
							// 后退
							if (!item6.isEnabled()) {
								item6.setEnabled(true);
							}
							main.setInfo("欢迎使用 Hunter 1.0", Color.BLACK);
						} else {
							main.setInfo("无效的页码 " + i, Color.RED);
							formatField1.selectAll();
						}
					}
				});
			}
		});
		// 后退事件,只能后退一次
		item6.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				main.setInfo("执行中,请稍候...", Color.BLUE);
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						subDatas = pageTool.getPageDatas(lastPage);
						editPanel1.setText(SystemUtil.getPageInfo(subDatas));
						setOpenFileDirItems();
						// 检查按钮可用性
						checkButtons();
						item6.setEnabled(false);
						main.setInfo("欢迎使用 Hunter 1.0", Color.BLACK);
					}
				});

			}
		});
		// 全选事件
		this.item3.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				editPanel1.requestFocus();
				editPanel1.selectAll();
			}
		});
		// 复制事件
		this.item4.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				editPanel1.copy();
			}
		});
		// 属性事件
		this.item5.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				if (subDatas == null || subDatas.size() == 0) {
					SwingUtil.showNormalInfo(main, "搜索 " + keyWord + " 无结果!",
							"属性");
				} else {
					StringBuilder sb = new StringBuilder();
					sb.append("搜索关键字: " + keyWord + "\n");
					sb.append("搜索用时: "
							+ SystemUtil.formatNumber((times / 1000d), "0.00")
							+ "秒\n");
					sb.append("搜索结果: " + pageTool.getDatasSize() + "条\n");
					sb.append("页码: " + pageTool.getCurrpage() + "/"
							+ pageTool.getTotalpages() + "\n");
					SwingUtil.showDetailInfo(main, "属性", sb, 5, 30);
				}

			}
		});
		// 打开文件所在目录事件
		ActionListener openDirAction = new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				final String file = e.getActionCommand();
				main.setInfo("正在打开,请稍候...", Color.BLUE);
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						try {
							FileData fd = getUserData(file);
							if (fd != null) {
								// 判断对应的文件是否存在
								if (isOpenFileExist(fd)) {
									SystemUtil.openDir4File(fd
											.getAbsolutePath());
									main.setInfo("打开完成", Color.BLUE);
								}
							} else {
								main.setInfo("文件 " + file + " 对应目录为空,无法打开!",
										Color.RED);
							}
						} catch (Exception ex) {
							log.debug("打开文件 " + file + " 所在目录时异常!", ex);
							main.setInfo("打开文件 " + file + " 所在目录时异常!",
									Color.RED);
							// save log
							LogUtil.saveExceptionLog(ex);
						}
					}
				});

			}
		};
		for (int i = 0; i < this.fileItems.length; i++) {
			fileItems[i].addActionListener(openDirAction);
		}
		// 搜索事件
		ActionListener action = new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				search();
			}
		};
		this.textField1.addActionListener(action);
		this.button1.addActionListener(action);
		// lost focus event for textfield
		this.textField1.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent e) {
				if (!e.isTemporary()) {
					// dispose window
					disposeWindow();
				}
			}
		});
		// 点击打开事件
		this.editPanel1.addHyperlinkListener(new HyperlinkListener() {

			public void hyperlinkUpdate(HyperlinkEvent e) {
				// 获取点击的文件名
				final String name = e.getDescription();
				if (HyperlinkEvent.EventType.ACTIVATED == e.getEventType()) {
					main.setInfo("正在打开,请稍候...", Color.BLUE);
					EventQueue.invokeLater(new Runnable() {
						public void run() {
							try {
								FileData fd = getUserData(name);
								if (fd != null) {
									if (isOpenFileExist(fd)) {
										SystemUtil.openFile(fd
												.getAbsolutePath());
										main.setInfo("打开完成", Color.BLUE);
									}
								} else {
									main.setInfo("错误,无法打开 " + name, Color.RED);
								}
							} catch (Exception ex) {
								log.debug("打开" + name + "异常!", ex);
								main.setInfo("打开" + name + "异常!", Color.RED);
								// save log
								LogUtil.saveExceptionLog(ex);
							}
						}
					});
				} else if (HyperlinkEvent.EventType.ENTERED == e.getEventType()) {
					main.setInfo("点击打开 " + name, Color.BLACK);
				} else if (HyperlinkEvent.EventType.EXITED == e.getEventType()) {
					main.setInfo("欢迎使用 Hunter 1.0", Color.BLACK);
				}

			}
		});
		/*
		 * 自动补全事件
		 */
		this.textField1.getDocument().addDocumentListener(
				new DocumentListener() {

					@Override
					public void removeUpdate(DocumentEvent e) {
						autoComplate();
					}

					@Override
					public void insertUpdate(DocumentEvent e) {
						autoComplate();
					}

					@Override
					public void changedUpdate(DocumentEvent e) {
						// Do nothing in here
					}
				});
		/**
		 * 搜索框查看历史搜索词事件(点击键盘PageUP,PageDown键触发)
		 */
		this.textField1.addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {
				// Do nothing in here
			}

			@Override
			public void keyReleased(KeyEvent e) {
				if (KeyEvent.VK_PAGE_DOWN == e.getKeyCode()) {
					String nkey = historyUtil.getNextKeyword();
					if (SystemUtil.hasText(nkey)) {
						textField1.setText(nkey);
					}
				}
				if (KeyEvent.VK_PAGE_UP == e.getKeyCode()) {
					String nkey = historyUtil.getPreviousKeyword();
					if (SystemUtil.hasText(nkey)) {
						textField1.setText(nkey);
					}
				}
			}

			@Override
			public void keyPressed(KeyEvent e) {
				// Do nothing in here
			}
		});
	}

	/**
	 * 处理打开的文件是否存在的问题
	 * 
	 * @param fd
	 *            FileData对象
	 * @return
	 */
	private boolean isOpenFileExist(final FileData fd) {
		String path = fd.getAbsolutePath();
		File f = new File(path);
		if (f.exists()) {
			return true;
		}
		// 弹出确认框
		JPanel panel = new JPanel();
		panel.setLayout(new GridLayout(2, 1));
		JLabel l = new JLabel(path + " 已经被删除!");
		panel.add(l);
		checkBox1 = new JCheckBox("删除对应的索引信息");
		checkBox1.setForeground(Color.GRAY);
		panel.add(checkBox1);
		JOptionPane.showMessageDialog(main, panel, "打开失败",
				JOptionPane.WARNING_MESSAGE);
		if (checkBox1.isSelected()) {
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					Writable w = null;
					try {
						// 调用删除对应索引文件的方法
						w = ConfigManager.getManager().getWriter();
						w.remove(fd);
						w.commit();
						// rebuild
						ConfigManager.getManager().updateSearchable();
					} catch (Exception e) {
						if (w != null) {
							// rollback
							try {
								w.rollback();
							} catch (IndexException e1) {
								log.debug(e1);
								LogUtil.saveExceptionLog(e1);
							}
						}
						log.debug(e);
						LogUtil.saveExceptionLog(e);
					}
				}
			});
		}
		return false;
	}

	/**
	 * 搜索事件
	 */
	private void search() {
		String s = this.textField1.getText().trim();
		if (s.length() == 0) {
			main.setInfo("输入为空,不能搜索", Color.RED);
			return;
		}
		/*
		 * If complete window is show and have select value ,get the value to
		 * keyword
		 */
		if (window != null && window.isVisible()) {
			if (list.getSelectedIndex() != -1) {
				s = list.getSelectedValue().toString();
				textField1.setText(s);
			}
		}
		disposeWindow();
		final String keyword = s;
		main.setInfo("正在搜索,请稍候...", Color.BLUE);
		this.textField1.setEnabled(false);
		this.button1.setEnabled(false);
		this.keyWord = s;
		SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
			// 进度条
			private JProgressBar bar = main.getjProgressBar1();
			// 保存搜索结果的集合对象
			private List<FileData> resList = new ArrayList<FileData>();

			protected Void doInBackground() throws Exception {
				bar.setVisible(true);
				long start = System.currentTimeMillis();
				QuerySession querySession = null;
				try {
					publish(5);
					Searchable searcher = ConfigManager.getManager()
							.getSearcher();
					publish(10);
					// 根据用户的设置创建查询对象Query, 默认使用IK查询
					Query query = QueryManager.getQueryManager().getQuery(
							keyword);
					publish(20);
					querySession = searcher.createQuerySession(query);
					publish(40);
					querySession.execute();
					publish(60);
					while (querySession.hasMore()) {
						resList.add((FileData) querySession.next());
					}
					publish(80);
					// 搜索时间
					long times = (System.currentTimeMillis() - start);
					// 更新搜索结果
					pageTool.setNewDatas(resList);
					setSearchResultInfo(resList.size(), times);
					checkButtons();
					publish(90);
					// 显示搜索数据
					if (resList.size() > 0) {
						subDatas = pageTool.getFirstpageDatas();
						editPanel1.setText(SystemUtil.getPageInfo(subDatas));
						setOpenFileDirItems();
					} else {
						editPanel1.setText(SystemUtil
								.getNullResultInfo(keyword));
						openMenu.setEnabled(false);
					}
					// 更新分页数据
					setPagesInfo(pageTool.getTotalpages(),
							PropertiesUtil.DEFAULT_PAGE_SIZE);
					publish(100);
					// Save keyword
					historyUtil.saveKeyword(keyword);
				} catch (Exception e) {
					log.debug("搜索异常", e);
					// 保存异常日志
					LogUtil.saveExceptionLog(e);
					// 弹出错误信息显示界面
					main.setInfo("搜索异常", Color.RED);
					SwingUtil.showErrorInfo(main, "异常", "搜索异常,信息:\n"
							+ e.getMessage());
				} finally {
					if (querySession != null) {
						querySession.close();
					}
				}
				return null;
			}

			protected void process(List<Integer> chunks) {
				for (int i : chunks) {
					bar.setValue(i);
				}
			}

			protected void done() {
				main.setInfo("搜索完成", Color.BLUE);
				textField1.setEnabled(true);
				button1.setEnabled(true);
				bar.setVisible(false);
				editPanel1.requestFocus();
				lastPage = 0;
				item6.setEnabled(false);
				// 处理查询结果为空的情况
				if (resList.size() == 0) {
					textField1.requestFocus();
					textField1.selectAll();
				}
			}
		};
		worker.execute();
	}

	/**
	 * 查找指定的UserData
	 * 
	 * @param name
	 *            文件名
	 * @return
	 */
	private FileData getUserData(String name) {
		if (this.subDatas != null) {
			for (UserData ud : subDatas) {
				if (ud instanceof FileData) {
					FileData rf = (FileData) ud;
					// 根据文件名相同来判断
					if (name.equalsIgnoreCase(rf.getFileName())) {
						return rf;
					}
				}
			}
		}
		return null;
	}

	/**
	 * 自动补全的实现方法
	 */
	private void autoComplate() {
		// Check whether first show,if is first show,not allow auto complete.
		if (firstShow) {
			return;
		}
		// Check switch
		if (!PropertiesUtil.AUTO_COMPLATE_OPEN) {
			return;
		}
		// Check input text
		String key = textField1.getText().trim();
		if (!SystemUtil.hasText(key)) {
			disposeWindow();
			return;
		}
		String results[] = ConfigManager.getManager().suggestion(key);
		if (results == null || results.length == 0) {
			disposeWindow();
			return;
		}
		// Open window
		showAutocompleteWindow(results);
	}

	/**
	 * Show autocomplete window
	 * 
	 * @param results
	 *            Search results
	 */
	private void showAutocompleteWindow(String[] results) {
		// Create window
		createWindow(results.length);
		list = new JList(results);
		list.setBorder(BorderFactory.createLineBorder(Color.black));
		window.add(list, BorderLayout.CENTER);
		window.setVisible(true);
		textField1.requestFocus();
		// add event
		list.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (list.getSelectedIndex() != -1) {
					textField1.setText(list.getSelectedValue().toString());
					search();
				}
			}
		});
		// Mouse move event
		list.addMouseMotionListener(new MouseMotionAdapter() {
			@Override
			public void mouseMoved(MouseEvent e) {
				int index = list.locationToIndex(e.getPoint());
				if (list.getSelectedIndex() != index) {
					list.setSelectedIndex(index);
				}
			}
		});
		// Mouse exist event
		list.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseExited(MouseEvent e) {
				list.clearSelection();
			}
		});
	}

	/**
	 * Create autocomplete window,if have old window,then dispose old, after
	 * create new window
	 * 
	 * @param length
	 *            Search results size
	 */
	private void createWindow(int length) {
		disposeWindow();
		window = new JWindow(main);
		window.setLayout(new BorderLayout());
		Point point = textField1.getLocationOnScreen();
		window.setLocation(point.x, point.y + 20);
		window.setSize(textField1.getSize().width, 18 * length);
	}

	/**
	 * Dispose auto complete window,if it is visible true
	 * <p>
	 * Current package can visit
	 */
	void disposeWindow() {
		if (window != null) {
			if (window.isVisible()) {
				window.dispose();
			}
		}
	}

	public void setFirstShow(boolean firstShow) {
		this.firstShow = firstShow;
	}

}
